#include <iostream>

#include "Item.h"
#include "Random.h"

using namespace std;

int Item::m_staticID = 0;

/**
 * Constructor
 * Set all members to zero and get current ID
 */
Item::Item()
{
	m_strName = "";
	m_strDesc = "";
	m_iType = ITEM_TYPE_UNKNOWN;
	m_iPrice = 0;
	m_iDamage = 0;
	m_iArmorBypass.mLow = 0;
	m_iArmorBypass.mHigh = 0;
	m_iArmorFactor = 0;
	m_id = getNextID();
}


/**
 * Constructor
 * Set all members with Parameters and get current ID
 * @param std::string name
 * @param std::string desc 
 * @param int type
 * @param int price
 * @param int damage
 * @param int armorBypassLow
 * @param int armorBypassHigh
 * @param int armorFactor
 */
Item::Item(std::string name, 
		   std::string desc, 
		   int type, 
		   int price, 
		   int damage, 
		   int armorBypassLow, 
		   int armorBypassHigh, 
		   int armorFactor)
{
	m_strName = name;
	m_strDesc = desc;
	m_iType = type;
	m_iPrice = price;
	m_iDamage = damage;
	m_iArmorBypass.mLow = armorBypassLow;
	m_iArmorBypass.mHigh = armorBypassHigh;
	m_iArmorFactor = armorFactor;
	m_id = getNextID();
}


/**
 * Destructor
 */
Item::~Item()
{

}


/**
 * operator=
 * Overloaded assigment operator.
 * @param const Item& itemToCopy - which is the Class to copy
 * @return Item& - a reference to the copied Class
 *
 */
Item& Item::operator=(const Item& itemToCopy)
{
	if (this != &itemToCopy)
	{
		m_id = getNextID();
		m_strName = itemToCopy.m_strName;
		m_strDesc = itemToCopy.m_strDesc;
		m_iType = itemToCopy.m_iType;
		m_iPrice = itemToCopy.m_iPrice;
		m_iDamage = itemToCopy.m_iDamage;
		m_iArmorBypass.mLow = itemToCopy.m_iArmorBypass.mLow;
		m_iArmorBypass.mHigh = itemToCopy.m_iArmorBypass.mHigh;
		m_iArmorFactor = itemToCopy.m_iArmorFactor;
	}
	return *this;
}


/**
 * Returns a bypass roll. The higher the better.
 * @param void
 * @return int - a random number for the bypass
 */
int Item::getBypassRoll()
{
	return (Random(getBypassRollLow(), getBypassRollHigh()));
}


/**
 * Get next ID
 * @param void
 * @return int - 
 */
int Item::getNextID()
{
	++m_staticID;
	return (m_staticID);
}


/**
 * Get current ID
 * @param void
 * @return int - 
 */
int Item::getId()
{
	return m_id;
}


/**
 * Set name of the Item
 * @param std::string val
 * @return void
 */
void Item::setName(std::string val)
{
	m_strName = val;
}


/**
 * Set description of the Item
 * @param std::string val
 * @return void
 */
void Item::setDesc(std::string val)
{
	m_strDesc = val;
}


/**
 * Set Type of the Item
 * @param int val
 * @return void
 */
void Item::setType(int val)
{
	m_iType = val;
}


/**
 * Set Price of the Item
 * @param int val
 * @return void
 */
void Item::setPrice(int val)
{
	m_iPrice = val;
}


/**
 * Get type of the Item
 * @param void
 * @return int - Get type of the Item
 */
int Item::getType()
{
	return m_iType;
}


/**
 * Set Damage of the Item
 * @param int val
 * @return void
 */
void Item::setDamage(int val)
{
	m_iDamage = val;
}


/**
 * Set Bypass roll
 * @param int low
 * @param int high
 * @return void
 */
void Item::setBypassRoll(int low, int high)
{
	m_iArmorBypass.mLow = low;
	m_iArmorBypass.mHigh = high;
}


/**
 * Set Armor Factor of the Item
 * @param int val
 * @return void
 */
void Item::setArmorFactor(int val)
{
	m_iArmorFactor = val;
}


/**
 * Prints ID/Name/Type
 * @param void
 * @return void
 */
void Item::miniPrint()
{
	cout << m_id << ") " << m_strName << " [";
	switch(m_iType)
	{
	case ITEM_TYPE_UNKNOWN:
		cout << "Unknown";
		break;
	case ITEM_TYPE_ARMOR:
		cout << "Armor";
		break;
	case ITEM_TYPE_ONEHANDEDWEAPON:
		cout << "One handed weapon";
		break;
	case ITEM_TYPE_TWOHANDEDWEAPON:
		cout << "Two handed weapon";
		break;
	default:
		cout << "Type: " << "!!! Error !!!";
		break;
	}
	cout << "] " << endl;
}


/**
 * Prints All Item information
 * @param void
 * @return void
 */
void Item::print()
{
	cout << "----------------ITEM--------------" << endl;
	cout << "ItemID: " << m_id << endl;
	cout << "Name: " << m_strName << endl;
	cout << "Description: " << m_strDesc << endl;
	cout << "Price: " << m_iPrice << " florins" << endl;
	switch(m_iType)
	{
	case ITEM_TYPE_UNKNOWN:
		cout << "Type: " << "Unknown" << endl;
		break;
	case ITEM_TYPE_ARMOR:
		cout << "Type: " << "Armor" << endl;
		cout << "Armor factor: " << m_iArmorFactor << endl;
		break;
	case ITEM_TYPE_ONEHANDEDWEAPON:
		cout << "Type: " << "One handed weapon" << endl;
		cout << "Armor bypass: (" << m_iArmorBypass.mLow << ", " << m_iArmorBypass.mHigh << ")" << endl;
		cout << "Damage: " << m_iDamage << endl;
		break;
	case ITEM_TYPE_TWOHANDEDWEAPON:
		cout << "Type: " << "Two handed weapon" << endl;
		cout << "Armor bypass: (" << m_iArmorBypass.mLow << ", " << m_iArmorBypass.mHigh << ")" << endl;
		cout << "Damage: " << m_iDamage << endl;
		break;
	default:
		cout << "Type: " << "!!! Error !!!" << endl;
		break;
	}
	cout << "------------------------------------------------" << endl;
}


/**
 * Get Name of Item
 * @param void
 * @return std::string - name of Item
 */
std::string Item::getName()
{
	return m_strName;
}


/**
 * Get Description of Item
 * @param void
 * @return std::string - description of Item
 */
std::string	Item::getDesc()
{
	return m_strDesc;
}


/**
 * Get Price of Item
 * @param void
 * @return int - Price of Item
 */
int Item::getPrice()
{
	return m_iPrice;
}


/**
 * Get Damage of Item
 * @param void
 * @return int - Damage of Item
 */
int Item::getDamage()
{
	return m_iDamage;
}


/**
 * Get lower range of Bypass roll
 * @param void
 * @return int -
 */
int Item::getBypassRollLow()
{
	return m_iArmorBypass.mLow;
}


/**
 * Get higher range of Bypass roll
 * @param void
 * @return int -
 */
int Item::getBypassRollHigh()
{
	return m_iArmorBypass.mHigh;
}


/**
 * Get Armor factor
 * @param void
 * @return int -
 */
int Item::getArmorFactor()
{
	return m_iArmorFactor;
}

